
#ifndef ANDROID_GLTEST_CAMERA_H
#define ANDROID_GLTEST_CAMERA_H

#include <android/log.h>
#include <android/bitmap.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <linux/usbdevice_fs.h>

#include <utils/Log.h>
#include <utils/RefBase.h>
#include <utils/threads.h>

#include "FrameQueue.h"
#include "bmp_header.h"
#include "pixel.h"

#define  LOGI(...)		__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)		__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

#define CLEAR(x)		memset (&(x), 0, sizeof (x))

#define IMG_WIDTH		640
#define IMG_HEIGHT		480

#define ERROR_LOCAL		-1
#define SUCCESS_LOCAL	0

namespace android {

struct bmp_bgr {
   uint8_t blue;
   uint8_t green;
   uint8_t red;
};


const tagBITMAPFILEHEADER  bfile {
	.bfType = 0x4d42,	//"BM"
	.bfSize = IMG_WIDTH*IMG_HEIGHT*3+0x36,	//frame size + headers
	.bfReserved1 = 0,	
	.bfReserved2 = 0,	
	.bfOffBits = 0x36
};

const tagBITMAPINFOHEADER  binfo {
	.biSize = 0x28,		//sizeof(BITMAPINFOHEADER)
	.biWidth = IMG_WIDTH,
	.biHeight = IMG_HEIGHT,
	.biPlanes = 1,
	.biBitCount = 0x18,	//24-bit true color
	.biCompression = 0,	//no compress
	.biSizeImage = 0,	//?
	.biXPelsPerMeter = 0,//0x0b40,	//?
	.biYPelsPerMeter = 0,//0x0b40,	//?
	.biClrUsed = 0,		//?
	.biClrImportant = 0	//?
};




struct buffer {
	void * start;
	size_t length;
};

class CameraDevice : public Thread, public virtual RefBase {

private:    
    char dev_name[16];
    int fd ;
    struct buffer * buffers = NULL;
    unsigned int n_buffers = 0;
    
    int camerabase = -1;
    int * rgb = NULL;
    int * ybuf = NULL;
    
    int yuv_tbl_ready=0;
    int y1192_tbl[256];
    int v1634_tbl[256];
    int v833_tbl[256];
    int u400_tbl[256];
    int u2066_tbl[256];

    sp<FrameQueue> mQueue;

public:
    CameraDevice(sp<FrameQueue> q);
    ~CameraDevice();

    int errnoexit(const char *s);
    int xioctl(int fd, int request, void *arg);
    int opendevice(int videoid);
    int initdevice(void);
    int initmmap(void);
    int startcapturing(void);
    int readframeonce(void);
    int readframe(void);
    void processimage (const void *p);
    int stopcapturing(void);
    int uninitdevice(void);
    int closedevice(void);
    void yuyv422toABGRY(unsigned char *src);

private:
    virtual bool        threadLoop();
    virtual status_t    readyToRun();
    virtual void        onFirstRef();


    void yCbCr422_normalization(struct yuv422_sample *yuv422_samp_in,
			  struct yuv422_sample *yuv422_samp_out);

    void yuyv422toBMP(uint8_t *frame);
};

}   // namespace android
#endif  // ANDROID_GLTEST_CAMERA_H
